<template>
  <div class="ttt-confirm" ref="confirmDom" :class="{ close: confirmClose }" :style="confirmStyle">
    <div class="ttt-confirm-title" v-if="showTitle">
      <span>{{ title }}</span>
      <em v-if="showClose" @click="cancelClick('close', 'icon')"><i class="iconfont icon-multiply fs10" /></em>
    </div>
    <div class="content">
      <slot></slot>
      <span>{{ content }}</span>
    </div>
    <div class="footer">
      <t-button
        class="mr15"
        v-if="showCancelButton"
        :loading="cancelLoading"
        :radius="roundButton"
        @click="cancelClick('cancel', 'btn')"
      >
        {{ cancelText }}
      </t-button>
      <t-button
        type="primary"
        v-if="showDefineButton"
        :loading="defineLoading"
        :radius="roundButton"
        @click="defineClick"
      >
        {{ defineText }}
      </t-button>
    </div>
  </div>
  <div
    class="ttt-confirm-modal"
    v-if="showModal"
    :class="{ close: confirmClose }"
    @click="cancelClick('close', 'modal')"
  />
</template>

<script lang="ts">
import TButton from '../../TButton/TButton.vue'
import mitt from 'mitt'
import { computed, defineComponent, ref } from 'vue'
import { getPropsSize } from '../../utils/utils'
import type { PropType, CSSProperties } from 'vue'
import type { Emitter } from 'mitt'

export declare interface ConfirmProps {
  title: string
  width: string
  content: string
  defineText: string
  cancelText: string
  showClose: boolean
  showTitle: boolean
  showModal: boolean
  closeOnModal: boolean
  showCancelButton: boolean
  showDefineButton: boolean
  roundButton: boolean
}

export default defineComponent({
  name: 'tttConfirm',
  props: {
    // 标题
    title: {
      type: String as PropType<string>,
      default: '提示'
    },
    // 宽度
    width: {
      type: String as PropType<string>,
      default: '650rem'
    },
    // 内容
    content: {
      type: String as PropType<string>,
      default: null
    },
    // 确定按钮文字
    defineText: {
      type: String as PropType<string>,
      default: '确定'
    },
    // 取消按钮文字
    cancelText: {
      type: String as PropType<string>,
      default: '取消'
    },
    // 是否显示关闭按钮
    showClose: {
      type: Boolean as PropType<boolean>,
      default: true
    },
    // 是否显示标题
    showTitle: {
      type: Boolean as PropType<boolean>,
      default: true
    },
    // 是否模态层
    showModal: {
      type: Boolean as PropType<boolean>,
      default: true
    },
    // 是否通过遮罩层关闭
    closeOnModal: {
      type: Boolean as PropType<boolean>,
      default: true
    },
    // 是否显示取消按钮
    showCancelButton: {
      type: Boolean as PropType<boolean>,
      default: true
    },
    // 是否显示确定按钮
    showDefineButton: {
      type: Boolean as PropType<boolean>,
      default: true
    },
    // 圆角按钮
    roundButton: {
      type: Boolean as PropType<boolean>,
      default: false
    }
  },
  components: {
    TButton
  },
  setup(props: ConfirmProps) {
    const confirmMitt: Emitter<{ close: 'close' | 'cancel'; define: 'define' }> = mitt()
    // 组件dom
    const confirmDom = ref<HTMLElement>()
    // 是否关闭
    const confirmClose = ref<boolean>(false)
    // 是否关闭
    const defineLoading = ref<boolean>(false)
    // 是否关闭
    const cancelLoading = ref<boolean>(false)
    // 弹窗样式
    const confirmStyle = computed<CSSProperties>((): CSSProperties => {
      const width = getPropsSize(props.width, 650)
      return {
        width: `${width}rem`
      }
    })
    // 取消/关闭点击
    const cancelClick = (type: 'close' | 'cancel', from: 'btn' | 'modal' | 'icon' | 'esc'): void => {
      if (!props.closeOnModal && from === 'modal') return
      confirmMitt.emit('close', type)
    }
    // 确定关闭
    const defineClick = (): void => {
      confirmMitt.emit('define', 'define')
    }
    // 关闭事件
    const closeConfirm = (): void => {
      confirmClose.value = true
    }
    // 设置取消的loading
    const setCancelLoading = (val: boolean): void => {
      cancelLoading.value = val
    }
    // 设置确定的loading
    const setDefineLoading = (val: boolean): void => {
      defineLoading.value = val
    }

    return {
      confirmMitt,
      confirmDom,
      confirmClose,
      defineLoading,
      cancelLoading,
      confirmStyle,
      setCancelLoading,
      setDefineLoading,
      closeConfirm,
      cancelClick,
      defineClick
    }
  }
})
</script>

<style scoped lang="scss">
@keyframes pop-ups-enter {
  from {
    transform: translateX(-50%) translateY(-50%) scale(0.5);
    opacity: 0;
  }
  to {
    transform: translateX(-50%) translateY(-50%) scale(1);
    opacity: 1;
  }
}

@keyframes pop-ups-leave {
  from {
    transform: translateX(-50%) translateY(-50%) scale(1);
    opacity: 1;
  }
  to {
    transform: translateX(-50%) translateY(-50%) scale(0.5);
    opacity: 0;
  }
}

@keyframes modal-enter {
  from {
    background-color: rgba(0, 0, 0, 0);
  }
  to {
    background-color: rgba(0, 0, 0, 0.5);
  }
}

@keyframes modal-leave {
  to {
    background-color: rgba(0, 0, 0, 0);
  }
}

.ttt-confirm {
  position: fixed;
  z-index: 10;
  left: 50%;
  top: 50%;
  transform: translateX(-50%) translateY(-50%);
  background-color: var(--theme-bg);
  animation: pop-ups-enter 0.15s;
  border-radius: var(--modal-rudias);

  &.close {
    animation: pop-ups-leave 0.15s forwards;
  }

  > .ttt-confirm-title {
    cursor: move;
    padding: 20rem 30rem 10rem 20rem;
    position: relative;
    color: #000;
    font-size: 32rem;

    > span {
      display: inline-block;
    }

    > em {
      position: absolute;
      right: 20rem;
      cursor: pointer;
    }
  }

  > .content {
    padding: 10rem 20rem;
  }

  > .footer {
    padding: 10rem 20rem 20rem 20rem;
    display: flex;
    justify-content: flex-end;
  }
}

.ttt-confirm-modal {
  position: fixed;
  left: 0;
  top: 0;
  width: 100vw;
  height: 100vh;
  background-color: var(--theme-modal);
  animation: modal-enter 0.15s;

  &.close {
    animation: modal-leave 0.15s forwards;
  }
}
</style>
